﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Diagnostics;
using PSE.Tools.SchemaComparer.Extractor;
using System.Threading;

namespace PSE.Tools.SchemaComparer.WindowsApp
{
    /// <summary>
    /// Interaction logic for UcExtractor.xaml
    /// </summary>
    public partial class UcExtractor : UserControl
    {
        public UcExtractor()
        {
            InitializeComponent();
            Working = new ManualResetEvent(false);
        }
        #region Extract
        private BackgroundWorker _bgExtract;
        public MainWindow ParentWindow
        {
            get;
            set;
        }
        public ManualResetEvent Working
        {
            get;
            private set;
        }

        internal class ExtractParameter
        {
            public string DataSource
            {
                get;
                set;
            }

            public string UserName
            {
                get;
                set;
            }

            public string Password
            {
                get;
                set;
            }

            public string File
            {
                get;
                set;
            }

            public bool CompactFile
            {
                get;
                set;
            }
        }

        private void btnExtract_Click(object sender, RoutedEventArgs e)
        {
            ExtractParameter parm = new ExtractParameter();
            StringBuilder erroMessage = new StringBuilder();

            parm.DataSource = txtDataSource.Text.Trim();
            parm.UserName = txtUserName.Text.Trim();
            parm.Password = txtPassword.Password.Trim();
            parm.File = txtFile.Text.Trim();
            parm.CompactFile = chkCompactFile.IsChecked.GetValueOrDefault();

            if (string.IsNullOrEmpty(parm.DataSource))
                erroMessage.AppendLine("- Data Source deve ser informado");

            if (string.IsNullOrEmpty(parm.UserName))
                erroMessage.AppendLine("- User Name deve ser informado");

            if (string.IsNullOrEmpty(parm.Password))
                erroMessage.AppendLine("- Password deve ser informado");

            if (string.IsNullOrEmpty(parm.File))
                erroMessage.AppendLine("- Arquivo de Saída deve ser informado");

            if (erroMessage.Length > 0)
            {
                MessageBox.Show(erroMessage.ToString());
                return;
            }

            ShowLoadingPanel("Extraindo Schema " + parm.DataSource + "." + parm.UserName);

            _bgExtract = new BackgroundWorker();
            _bgExtract.WorkerSupportsCancellation = true;
            _bgExtract.DoWork += new DoWorkEventHandler(bgExtract_DoWork);
            _bgExtract.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgExtract_RunWorkerCompleted);
            _bgExtract.RunWorkerAsync(parm);
        }

        void bgExtract_DoWork(object sender, DoWorkEventArgs e)
        {
            ExtractParameter parm = e.Argument as ExtractParameter;
            ExtractSchema(parm);
        }

        void bgExtract_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            HideLoadingPanel();
        }

        DBSchema dbSchema;
        private void ExtractSchema(ExtractParameter parm)
        {
            try
            {
                Working.Set();

                //SE HOUVE O CANCELAMENTO
                if (_bgExtract.CancellationPending)
                    return;

                DBConnectionInfo connInfo = new DBConnectionInfo()
                {
                    DataSource = parm.DataSource,
                    User = parm.UserName,
                    Password = parm.Password
                };

                dbSchema = new DBSchema();

                try
                {
                    dbSchema.LoadDataBaseObjects(connInfo);
                }
                catch (Exception ex)
                {
                    string message = "Erro ao carregar as informações de Schema da Base de Dados." + Environment.NewLine + ex.Message;
                    EventLog.WriteEntry("SchemaComparer.Extractor", message, EventLogEntryType.Error);
                    MessageBox.Show(message, "Schema Extractor", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                //SE HOUVE O CANCELAMENTO
                if (_bgExtract.CancellationPending)
                    return;

                try
                {
                    //abrir caixa de seleção de arquivo
                    dbSchema.SaveToXmlFile(parm.File, parm.CompactFile);
                }
                catch (Exception ex)
                {
                    string message = "Erro ao salvar as informações de Schema da Base de Dados." + Environment.NewLine + ex.Message;
                    EventLog.WriteEntry("SchemaComparer.Extractor", message, EventLogEntryType.Error);
                    MessageBox.Show(message, "Schema Extractor", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                //SE HOUVE O CANCELAMENTO
                if (_bgExtract.CancellationPending)
                    return;

                MessageBox.Show("Extração do Schema realizada com sucesso");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ocorreu um erro inesperado ao executar a extrãção de dados." + Environment.NewLine + ex.ToString());
            }
            finally
            {
                Working.Reset();
            }
        }

        private void btnFile_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.Filter = "Xml File |*.xml";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFile.Text = dialog.FileName;
            }
        }

        private void ShowLoadingPanel(string text)
        {
            if (ParentWindow != null)
                ParentWindow.ShowLoadingPanel(text);
        }

        private void HideLoadingPanel()
        {
            if (ParentWindow != null)
                ParentWindow.HideLoadingPanel();
        }

        public void AbortExtract()
        {
            if (_bgExtract.IsBusy)
            {
                _bgExtract.CancelAsync();

                if (dbSchema != null)
                    dbSchema.Abort();
            }
        }
        #endregion
    }
}
